<?php

/**
 * @author Ned
 *
 */
class Com_Basil_HBase_Client_Json extends Com_Basil_HBase_Client_Abstract {

	/**
	 * @var Zend_Rest_Client
	 */
	private $restClient;

	public function __construct($type, $uri, $params) {
		parent::__construct($type, $uri, $params);

		$this->restClient = new Com_Basil_Http_Client();
	}

	/**
	 * @param $tableName
	 * @param $columnFamilies
	 * @return unknown_type
	 */
	public function createNewTable($tableName, $columnFamilies) {
		$uri = $this->hbaseRestURI . "/table/$tableName/";

		$data = array(
	   		'TableSchema' => array ('ColumnFamilies' => $columnFamilies)
		);

		$jsonData = Zend_Json::encode($data);
		 

		$this->restClient->setHeaders('Content-Type','application/json');
		$this->restClient->setUri($uri);
		$this->restClient->setRawData($jsonData);
		$response = $this->restClient->request('PUT');

		if ($response->isError()) {
			throw new Com_Basil_HBase_Exception("Unable to create table [$tableName]");
		}
	}

	/**
	 * @param $tableName
	 * @param $rows Array of Com_Basil_HBase_Data_Row
	 * @return unknown_type
	 */
	public function insertUpdateRow($tableName, $rows) {
		$uri = $this->hbaseRestURI ."/$tableName/new-rows";

		$dataRow = array();
			
		foreach($rows as $row) {
			if (!is_a($row,'Com_Basil_HBase_Data_Row')) {
				throw new Com_Basil_HBase_Exception('Incorrect data type '.get_class($row));
			}
			$cells = array();
			foreach($row->columns as $column) {
				//$colName = base64_encode($column->columnName);
				$colName = $column->columnName;
				$data = base64_encode($column->data);
				$cells[$colName] = $data;
			}
			$rowkey = base64_encode($row->key);
			$newRow = array('Key'=>$rowkey, 'Columns'=>$cells);
			if ($row->checkOption != null) {
				$newRow['CheckOption'] = array('ColumnName'=>$row->checkOption->columnName, 'Value'=> base64_encode($row->checkOption->data));
			}
			$dataRow[] = $newRow;
		}

		$dataRow = array('Rows'=> $dataRow);

		$postData = Zend_Json::encode($dataRow);

		$this->restClient->setHeaders('Content-Type','application/json');
		$this->restClient->setUri($uri);
		$this->restClient->setRawData($postData);
		$response = $this->restClient->request('PUT');
		 
		if ($response->isError()) {
			throw new Com_Basil_HBase_Exception("Unable to insert/update table [$tableName]");
		}
		
		$numRows = Zend_Json::decode($response->getBody());
		return $numRows;
	}

	public function getRows($tableName, $rowKey, $maxRows = 0, $startFrom = null) {
		$uri = $this->hbaseRestURI ."/$tableName/$rowKey/";
		
		if ($maxRows > 0) {
			$this->restClient->setHeaders('X-Max-Rows',$maxRows);
		}			
		$this->restClient->setHeaders('Accept','application/json');
		$this->restClient->setUri($uri);			
		$response = $this->restClient->request('GET');

		if ($response->isError()) {
			throw new Com_Basil_HBase_Exception("Unable to receive from table [$tableName]");
		}

		$responseBody = $response->getBody();
		 
		$jsonResponse = Zend_Json::decode($responseBody);
		$jsonObj = $jsonResponse[0];
		$rows = array();

		foreach($jsonResponse as $jsonObj) {
			$key = base64_decode((string)$jsonObj['Key']);
			$columns = array();
			foreach($jsonObj['Columns'] as $colName => $colValue) {
				$columns[] = new Com_Basil_HBase_Data_Column($colName,base64_decode((string)$colValue),0);
			}
			$ret = new Com_Basil_HBase_Data_Row($key, $columns);
			$rows[] = $ret;
		}

		return $rows;
	}
	
	public function deleteRows($tableName, $rows) {
		$uri = $this->hbaseRestURI ."/$tableName/multi-rows";
		
		$dataRow = array();
			
		foreach($rows as $row) {
			if (!is_a($row,'Com_Basil_HBase_Data_Row')) {
				throw new Com_Basil_HBase_Exception('Incorrect data type '.get_class($row));
			}
			$rowkey = base64_encode($row->key);
			$newRow = array('Key'=>$rowkey);
			if ($row->checkOption != null) {
				$newRow['CheckOption'] = array('ColumnName'=>$row->checkOption->columnName, 'Value'=> base64_encode($row->checkOption->data));
			}
			$dataRow[] = $newRow;
		}
		
		$dataRow = array('Rows'=> $dataRow);
		
		$postData = Zend_Json::encode($dataRow);
		
		$this->restClient->setHeaders('Content-Type','application/json');
		$this->restClient->setUri($uri);
		$this->restClient->setRawData($postData);
		$response = $this->restClient->request('DELETE');
			
		if ($response->isError()) {
			throw new Com_Basil_HBase_Exception("Unable to delete from table [$tableName]");
		}
		
		$numRows = Zend_Json::decode($response->getBody());
		return $numRows;		
	}
	
	public function getRow($tableName, $rowKey) {
		$rows = $this->getRows($tableName, $rowKey);
		return $rows[0];
		
	}
}

?>